package com.emip.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.emip.bean.Store;
import com.emip.pojo.Data;
import com.emip.pojo.Report;
import com.emip.util.report.Comput;


public class ReportFormat {
	
	public final static String SECONDFORMAT = "yyyy-MM-dd HH:mm:ss";
	public final static String MINUTEFORMAT = "yyyy-MM-dd HH:mm";
	public final static String HOURFORMAT = "yyyy-MM-dd HH";
	public final static String DAYFORMAT = "yyyy-MM-dd";
	public final static String WEEKFORMAT = "yyyy-ww";
	public final static String MONTHFORMAT = "yyyy-MM";
	public final static String YEARFORMAT = "yyyy";
	
	public static String[] formEndDate(String startDate, String endDate, String format, int unit, int page, int size) throws Exception {
		SimpleDateFormat df = new SimpleDateFormat(format);
		return formEndDate(df.parse(startDate), df.parse(endDate), format, unit, page, size);
	}
	
	public static String[] formEndDate(Date startDate, Date endDate, String format, int unit, int page, int size) throws Exception {
		String[] dates = new String[2];
		SimpleDateFormat df = new SimpleDateFormat(format);
		Calendar start = Calendar.getInstance();
		start.setTime(startDate);
		Calendar end = Calendar.getInstance();
		end.setTime(endDate);
		
		start.set(unit, start.get(unit) + (page-1) * size);
		dates[0] = df.format(start.getTime());
		
		start.set(unit, start.get(unit) + page * size);
		dates[1] = df.format(start.getTime());
		
		if (start.compareTo(end) > 0) {
			dates[1] = df.format(endDate);
		}
		return dates;
	}
	
	public static long getCount(Date start, Date end, String format, int unit) throws Exception {
		long timeunit = 1000; //1秒
		
		switch(unit) {
		case Calendar.HOUR_OF_DAY: //小时
			timeunit *= 3600;
			return (end.getTime() - start.getTime())/timeunit;
		case Calendar.DATE: //天
			timeunit *= 3600 * 24;
			return (end.getTime() - start.getTime())/timeunit;
		case Calendar.WEEK_OF_YEAR: //周
			timeunit *= 3600 * 24 * 7;
			return (end.getTime() - start.getTime())/timeunit;
		case Calendar.MONTH://月
			Calendar startC = Calendar.getInstance();
			Calendar endC = Calendar.getInstance();
			startC.setTime(start);
			endC.setTime(end);
			return (endC.get(Calendar.YEAR) - startC.get(Calendar.YEAR)) * 12 + endC.get(Calendar.MONTH) - startC.get(Calendar.MONTH);
		case Calendar.YEAR://年
			return end.getYear() - start.getYear();
		default: //秒
			return (end.getTime() - start.getTime())/timeunit;
		}
	}
	
	public static long getCount(String startDate, String endDate, String format, int unit) throws Exception {
		SimpleDateFormat df = new SimpleDateFormat(format);
		
		Date start = df.parse(startDate);
		Date end = df.parse(endDate);
		return getCount(start, end, format, unit);
	}

	
	private Report report;
	private String currentDate;
	private Map<String, Object> row;
	private List<String> colNames;
	private List<String> indexes;
	private Map<String, Map<String, Object>> indicators;
	
	public ReportFormat() {
		report = new Report();
		indicators = new HashMap<String, Map<String, Object>>();
	}
	
	public <T> void appendBodyData(List<T> datas) {
		if (datas == null) return;
		for (int i = 0; i < datas.size(); i++) {
			Store data = (Store) datas.get(i);
			List<Map<String, Object>> bodys = this.report.getBodys();
			if (currentDate == null || !currentDate.equals(data.getTimeLabel())) {
				currentDate = data.getTimeLabel();
				row = new HashMap<String, Object>();
				bodys.add(row);
				row.put("time", data.getTimeLabel());
			}
			row.put(data.getItemID(), new Data(data.getValue(), data.getFlag()));
		}
	}
	
	public void appendFooterData(Map<String, Comput> itemComputs) {
		//"MEAN", "MAX", "MIN"
		for (Map.Entry<String, Comput> entry : itemComputs.entrySet()) {
			String key = entry.getKey();
			Comput comput = entry.getValue();
			String computName = comput.getComputName();
			Map<String, Object> indicator = indicators.get(computName);
			if (indicator == null) {
				indicator = new HashMap<String, Object>();
				indicators.put(computName, indicator);
				indicator.put("time", comput.getLabel());
			}
			String itemID = key.split("_")[2];
			try {
				indicator.put(itemID, comput.getResult());
			} catch (Exception e) {
				indicator.put(itemID, '0');
			}
		}
	}
	
	public void appendFooterData(String[] stats, String siteId, String itemId) {
		String[] computNames = new String[] {"MaxComput", "MinComput", "AverageComput", "ValidComput"};
		String[] computLabels = new String[] {"最大值", "最小值", "平均值", "有效率"};
		for (int i = 0; i < computNames.length; i++) {
			String computName = computNames[i];
			Map<String, Object> indicator = indicators.get(computName);
			if (indicator == null) {
				indicator = new HashMap<String, Object>();
				indicators.put(computName, indicator);
				indicator.put("time", computLabels[i]);
			}
			if (stats != null && stats[i] != null) {
				if (i == 3) {
					indicator.put(itemId, stats[i]);
				} else  {
					BigDecimal gd = new BigDecimal(stats[i]);
					DecimalFormat df = new DecimalFormat("#.##");
					indicator.put(itemId, df.format(gd));
				}
			} else {
				indicator.put(itemId, '0');
			}
		}
	}
	
	public Report getReport() {
		List<Map<String, Object>> footers = this.report.getFooters();
		for (Map.Entry<String, Map<String, Object>> entry : indicators.entrySet()) {
			footers.add(entry.getValue());
		}
		report.setColNames(colNames);
		report.setIndexes(indexes);
		return report;
	}
	
	public static String getDayFormat(Date date) {
		return getFormat(date, ReportFormat.DAYFORMAT);
	}
	
	public static String getHourFormat(Date date) {
		return getFormat(date, ReportFormat.HOURFORMAT);
	}
	
	public static String getMinuteFormat(Date date) {
		return getFormat(date, ReportFormat.MINUTEFORMAT);
	}
	
	public static String getSecondFormat(Date date) {
		return getFormat(date, ReportFormat.SECONDFORMAT);
	}
	
	public static String getFormat(Date date, String format) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	public List<String> getColNames() {
		return colNames;
	}

	public void setColNames(List<String> colNames) {
		this.colNames = colNames;
	}

	public List<String> getIndexes() {
		return indexes;
	}

	public void setIndexes(List<String> indexes) {
		this.indexes = indexes;
	}
}
